#include "PropMatrix.h"

CPropList::CPropList()
:m_emitStarted(UUTFalse)
{

};

CPropList::~CPropList()
{
	ClearAll();
};

void CPropList::AddItem(const UUTTString& id, const UUTTString& type,const UUTTString& str)
{
	CPropItem* pItem = CPropItemBuilder::MakeItem(id, type, str);

	if (pItem)
	{
		m_props.push_back(pItem);
	}
};

CPropList::EmitOpResult CPropList::EmitProps(IUUTPropReceiver* receiver)
{
	if (!receiver) return CPropList::EmitResult_NoReceiver;

	UUTBool bCanStartEmit = UUTFalse;
	if (!m_emitStarted)
	{
		m_emitStarted = UUTTrue;
		bCanStartEmit = UUTTrue;
		ResetPropPositionTo(m_props.end());
	}else{
		//find a position change and emit props in another loop
		UUTBool bSomePostionChanged = UUTFalse;
		itProp it = m_props.begin();

		for (; it != m_props.end(); ++it)
		{
			CPropItem* pItem = *it;
			if (!pItem) return CPropList::EmitResult_InternalError;

			itPropValue presentRead = pItem->PresentRead();

			if (pItem->End() == presentRead+1) //to the end, cannot change in this time
			{
				continue;
			}

			pItem->IncreasePresentRead();
			bSomePostionChanged = UUTTrue;
			break;
		}
		if (bSomePostionChanged){
			bCanStartEmit = UUTTrue;		
			ResetPropPositionTo(it);
		}
	}
	
	if (bCanStartEmit)
	{
		for (itProp it=m_props.begin(); it != m_props.end(); ++it)
		{
			CPropItem* pItem = *it;
			if (!pItem) return CPropList::EmitResult_InternalError;

			itPropValue presentRead = pItem->PresentRead();
			UUTPropValue* pValue = *presentRead;
			if (pValue) 
			{
				receiver->SetPropValue(pItem->GetID(), *pValue);
			}
		}
		return CPropList::EmitResult_OK;
	}else{ //no more props need to be emitted
		return CPropList::EmitResult_NoMoreProps;
	}
};

void CPropList::ClearAll()
{
	for (itProp it=m_props.begin(); it!=m_props.end();++it)
	{
		CPropItem* pItem = *it;
		SafeDelete(pItem);
	}
	m_props.clear();
};

void CPropList::ResetPropPositionTo(itProp end)
{
	for (itProp it=m_props.begin(); it!=end; ++it)
	{
		CPropItem* pItem = *it;
		if (pItem)
		{
			pItem->ResetPresentRead();
		}
	}
};